

from template import *
from struct import pack

OPTION_ZEROCODED = 128
OPTION_TRUSTED = 64
OPTION_RESEND = 32
OPTION_ACK = 16

HEADER_MAP={
    CATEGORY_LOW : pack(">bb",255,255),
    CATEGORY_MEDIUM : pack(">bb",255,255),
    CATEGORY_HIGH : pack(">b",255),
    CATEGORY_FIXED : ""
}

class Packet:
    """models a packet"""

    def __init__(self,tmpl,msg,isResend=False,ackAppended=False,ack_id=0,seq=0):
        """initialize a packet with a message template"""
        self._tmpl = tmpl
        self._msg = msg
        self._seq = seq
        self._isResend = isResend
        self._ackAppended = ackAppended
        self._ackId = ack_id
        self._klass = tmpl.klass
        self._trusted = tmpl.trusted
        self._zerocoded = tmpl.zerocoded!="Unencoded"
        self._id = tmpl.getId()

    def getSequenceNumber(self):
        """retrieve the sequence number"""
        return self._seq

    seq=property(getSequenceNumber)

    def createSeq(self):
        """creates the first 4 bytes with options and sequence"""
        # create the bitmask
        b=0
        if self._zerocoded: b=b|OPTION_ZEROCODED
        if self._trusted: b=b|OPTION_TRUSTED
        if self._isResend: b=b|OPTION_RESEND
        if self._ackAppended: b=b|OPTION_ACK

        # now add the sequence number to it 
        b=pack(">b",b)              # pack options
        s=pack(">L",self._seq)      # pack sequence number
        # now combine them
        sl = list(s)
        sl[0]=b
        s="".join(sl)
        return s

    def createPacketType(self):
        """creates the packet type info"""
        return HEADER_MAP[self._klass]+pack(">H",self._id)

    def createHeader(self):
        """create the header"""
        return self.createSeq()+self.createPacketType()

    def buildPacket(self):
        """Build the packet"""
        return self.createHeader()+self._msg.toBytes()

    toBytes = buildPacket
